package cn.xyz.repository.mongo;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import javax.annotation.Resource;

import cn.xyz.commons.ex.ServiceException;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.client.*;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.Morphia;
import org.mongodb.morphia.mapping.MappedClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.mongodb.MongoClient;
import com.shiku.mongodb.morphia.MorphiaRepository;

import cn.xyz.commons.constants.KConstants;
import cn.xyz.mianshi.utils.SKBeanUtils;
import cn.xyz.repository.IMongoDAO;

public abstract class MongoRepository<T,ID extends Serializable> extends MorphiaRepository<T,ID> implements IMongoDAO<T,ID> {

	protected Logger logger = LoggerFactory.getLogger(this.getClass());




	@Resource
	protected Morphia morphia;
	public Morphia getMorphia() {
		return morphia;
	}
//	protected Class<T> entityClass;// 实体类
	public abstract Datastore getDatastore();
	public abstract Class<T> getEntityClass();

	@Override
	public MongoClient getMongoClient() {
		return SKBeanUtils.getLocalSpringBeanManager().getMongoClient();
	}


	/**
	 * 获取 分库  分表 表名  分表 逻辑需要继承实现
	 * 分表 的类 必须实现 这个方法
	 * @param userId
	 * @return
	 */
	public String getCollectionName(int userId) {
		int remainder=0;
		if(userId>KConstants.MIN_USERID) {
			remainder=userId/KConstants.DB_REMAINDER.DEFAULT;
		}
		return String.valueOf(remainder);
	}

	/**
	 * @param id
	 * @param minNum 起始值
	 * @param startNum 取余数计算值
	 * @return
	 */
	public String getCollectionName(ObjectId id) {
		if (null == id) {
			logger.info(" ====  getCollectionName ObjectId is null  ====");
			throw new ServiceException("ObjectId  is  null !");
		} else {
			int remainder = 0;
			int counter = id.getCounter();
			remainder = counter / KConstants.DB_REMAINDER.DEFAULT;
			return String.valueOf(remainder);
		}
	}

	public static MongoCollection<Document> getCollection(MongoDatabase database, int userId) {
		int remainder=0;
		if(userId>KConstants.MIN_USERID) {
			remainder=userId/KConstants.DB_REMAINDER.DEFAULT;
		}
		return database.getCollection(String.valueOf(remainder));
	}
	public static String getRemainderName(int userId) {
		int remainder=0;
		if(userId>KConstants.MIN_USERID) {
			remainder=userId/KConstants.DB_REMAINDER.DEFAULT;
		}
		return String.valueOf(remainder);
	}



	public MongoCollection<Document> getMongoCollection(MongoDatabase database,int userId) {
		int remainder=0;
		if(userId>KConstants.MIN_USERID) {
			remainder=userId/KConstants.DB_REMAINDER.DEFAULT;
		}
		return database.getCollection(String.valueOf(remainder));
	}





	/**
	 * 根据 用户 Id 即 取余 值  获取 实体表名
	 * @param userId
	 * @param remainder  取余值
	 * @return
	 */
	public String getCollectionName(int userId,int remainder) {
		if(userId>KConstants.MIN_USERID) {
			remainder=userId/remainder;
		}
		return String.valueOf(remainder);
	}
	/**
	 * 获取  实体的表名
	 * @return
	 */
	public String getCollectionName() {
		MappedClass mappedClass = morphia.getMapper().getMappedClass(getEntityClass());
		if(null==mappedClass)
			return null;
		return mappedClass.getCollectionName();
	}

	public DBObject objectToDBObject(Object entity) {
		return morphia.toDBObject(entity);
	}



	/** 模糊查询
	 * @param name
	 * @param key
	 * @param roomId
	 * @return
	 */
	public List<Document> containsIgnoreCase(String name, String key, ObjectId roomId){
		List<Document> list = new ArrayList<Document>();
		Pattern pattern = Pattern.compile("^.*" + name +".*$", Pattern.CASE_INSENSITIVE);
		BasicDBObject query = new BasicDBObject();
		query.put("roomId",roomId);
		query.put(key,pattern);//key为表字段名
		FindIterable<Document> findIterable = getCollection(roomId).find(query);
		MongoCursor<Document> mongoCursor = findIterable.iterator();
		Document document = null;

		try {
			while(mongoCursor.hasNext()){
				document = mongoCursor.next();
				list.add(document);
			}
		} finally {
			if(null!=mongoCursor)
				mongoCursor.close();
		}
		return list;
	}



}
